package com.k3cloud.user.user;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.AES;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowObject;
import com.hustcad.plm.pdm.partbom.vo.PartDetailsVO;
import com.k3cloud.base.dto.HttpClientTokenDTO;
import com.k3cloud.base.dto.entity.ExecutionTypeDO;
import com.k3cloud.base.type.AttributesInterfaceType;
import com.k3cloud.rpc.http.RemoteSocketWrapper;
import com.k3cloud.rpc.http.service.RemoteProcedureCallService;
import com.k3cloud.rpc.utils.HttpMethodEnum;
import com.k3cloud.user.entity.AuthorizationEntity;
import com.k3cloud.user.entity.HttpClientTokenVO;
import com.k3cloud.user.service.UserK3cloudService;
import org.apache.http.client.methods.HttpRequestBase;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@AttributesInterfaceType(typeValue = "k3cloudProject",classificationValue = "MaterialsHandling")
public class TestRemoteProcedureCallService implements RemoteProcedureCallService {

    @Resource
    UserK3cloudService userK3cloudService;

    public TestRemoteProcedureCallService() {
    }

    /**
     * 返回金蝶的必要访问信息，返回参数会传到getToken方法
     * @return
     * @param <T>
     */
    @Override
    public <T> T getAuthorizationEntity() {
        Map<String,Object> map=new HashMap<>();
        map.put("title","金蝶云星空配置");
        List<Map<String,Object>> list=userK3cloudService.selectFiguration(map);
        if(list.size()>0){
            AuthorizationEntity authorizationEntity=new AuthorizationEntity();
            authorizationEntity.setAcctID((String) list.get(0).get("acctid"));
            authorizationEntity.setUsername((String) list.get(0).get("username"));
            authorizationEntity.setPassword(AES.decrypt((String) list.get(0).get("password"), "huazPlm@15999899"));
            return (T) authorizationEntity;
        }
        return null;
    }

    /**
     * 获取登录鉴权信息，返回的参数会传到changeHttpClientHeaders方法
     * @param authorizationEntity
     * @param obj
     * @return
     */
    @Override
    public HttpClientTokenDTO getToken(Object authorizationEntity, Object obj) {
        if (authorizationEntity instanceof AuthorizationEntity) {
            AuthorizationEntity authorization = (AuthorizationEntity) authorizationEntity;
            ExecutionTypeDO executionTypeDO = (ExecutionTypeDO) obj;
            String method = executionTypeDO.getMethod();
            String protocol = executionTypeDO.getProtocol();
            String port = executionTypeDO.getPort();
            String home = executionTypeDO.getHome();
            RemoteSocketWrapper remoteSocketWrapper = SpringUtil.getBean(RemoteSocketWrapper.class);
            try {
                StringBuilder stringBuilder = new StringBuilder();
                if("http".equals(protocol)){
                    stringBuilder.append(HttpMethodEnum.HTTP.value());
                }
                else if("https".equals(protocol)){
                    stringBuilder.append(HttpMethodEnum.HTTPS.value());
                }
                stringBuilder.append(home);
                if("80".equals(port)==false){
                    stringBuilder.append(":");
                    stringBuilder.append(port);
                }
                stringBuilder.append("/K3Cloud/Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc");

                HttpClientTokenVO httpClientTokenVO = null;
                JSONObject login=new JSONObject();
                login.put("acctID",authorization.getAcctID());
                login.put("lcid",2052);
                login.put("username",authorization.getUsername());
                login.put("password",authorization.getPassword());
                login.put("isKickOff",true);

                JSONObject httpResult = new JSONObject();
                if("post".equals(method)){
                    httpResult = remoteSocketWrapper.httpLoingToJSONObject(stringBuilder.toString(),login,null);
                }

                if(httpResult.containsKey("IsSuccessByAPI")){
                    if(httpResult.getBoolean("IsSuccessByAPI")){
                        Map<String,Object> threadContentMap=new HashMap<>();
                        threadContentMap.put("authorization",authorization);
                        httpClientTokenVO=new HttpClientTokenVO<Map<String,Object>>(threadContentMap);
                        httpClientTokenVO.setHeadTokenValue("kdservice-sessionid",httpResult.getString("KDSVCSessionId"));
                        httpClientTokenVO.setHeadTokenValue("Cookie",httpResult.getString("KDSVCSessionId"));
                    }
                }
                return httpClientTokenVO;
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        return null;
    }

    /**
     * 可向HttpClientTokenDTO添加参数，参数会传到changeHttpClientHeaders方法
     * @param httpClientTokenVO
     * @param partDetails
     * @param executionTypeDO
     */
    @Override
    public void setParameter(HttpClientTokenDTO httpClientTokenVO, PartDetailsVO partDetails, ExecutionTypeDO executionTypeDO, FlowObject flowObject, Object parameter) {
        Map<String,Object> threadContentMap= (Map<String, Object>) httpClientTokenVO.getThreadContent();
        threadContentMap.put("partDetails",partDetails);
    }

    /**
     * 可修改鉴权信息，http请求头信息
     * @param token
     * @param httpRequestBase
     */
    @Override
    public void changeHttpClientHeaders(HttpClientTokenDTO token, HttpRequestBase httpRequestBase, ExecutionTypeDO executionTypeDO) {
        Map<String,Object> authorization=token.getAuthorization();
        if(authorization!=null){
            for(Map.Entry<String,Object> entity: authorization.entrySet()){
                httpRequestBase.setHeader(entity.getKey(), (String) entity.getValue());
            }
        }
    }

    /**
     * 判断请求是否需要重新或取鉴权信息，如果返回true,会调用getAuthorizationEntity，
     * getToken，setParameter三个方法
     * @param obj
     * @return
     */
    @Override
    public boolean needReGetToken(Object obj, ExecutionTypeDO executionTypeDO) {
        return false;
    }

    /**
     * 发送请求前，可修改发送的结构outMap，返回值会直接替换outMap
     * @param token
     * @param outMap
     * @return
     */
    @Override
    public Map<String, Object> sendBefore(HttpClientTokenDTO token, Map<String, Object> outMap, ExecutionTypeDO executionTypeDO, FlowObject flowObject,Object parameter) {
        Map<String,Object> outParameter=new HashMap<>();
        outParameter.put("formid",executionTypeDO.getFormid());
        outParameter.put("data",JSONObject.toJSONString(outMap));

        return outParameter;
    }

    /**
     * 这里可调用提交和审核请求，返回值如果不等于null,会直接替换返回结果
     * @param result
     * @param executionTypeDO
     * @return
     */
    @Override
    public JSONObject sendAfter(JSONObject result, ExecutionTypeDO executionTypeDO, FlowObject flowObject,Object parameter) {
        return null;
    }

    /**
     * 校验返回结果，可修改返回结果
     * @param result
     * @return
     */
    @Override
    public JSONObject reconstructResult(JSONObject result, ExecutionTypeDO executionTypeDO) {

        return null;
    }
}
